package cn.hallele.leinsteining.ms.infrastructure.util.network;

import cn.hallele.leinsteining.mc.infrastructure.metadata.exceptions.children.ServiceCallException;
import cn.hallele.leinsteining.mc.infrastructure.metadata.io.Metric;
import cn.hallele.leinsteining.mc.infrastructure.metadata.io.Response;
import cn.hutool.extra.servlet.JakartaServletUtil;
import cn.hutool.http.Header;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Locale;

/**
 * http请求相关的拉工具类
 *
 * @author anle5
 * @since 2024/7/25 23:35
 */
@Slf4j
public class HttpUtil {
    public static final String TRANCE_ID_KEY = "TRANCE_ID";

    /**
     * 获取客户端ip
     *
     * @return 客户端ip
     */
    public static String getClientIp() {
        return JakartaServletUtil.getClientIP(getHttpServletRequest());
    }

    /**
     * 获取客户端设备信息
     *
     * @return platformName + version
     */
    public static String getClientInfo() {
        UserAgent clientUserAgent = getClientUserAgent();

        String osName = clientUserAgent.getOs().getName();
        String osVersion = clientUserAgent.getOsVersion();
        String browserName = clientUserAgent.getBrowser().getName();
        String browserVersion = clientUserAgent.getVersion();
        String engineName = clientUserAgent.getEngine().getName();
        String engineVersion = clientUserAgent.getEngineVersion();

        return osName + " " + osVersion
                + "|" + browserName + " " + browserVersion
                + "|" + engineName + " " + engineVersion;
    }

    /**
     * 从ContextHolder的请求中获取 Locale
     *
     * @return Locale, 获取不到返回默认
     */
    public static Locale getLocale() {
        String acceptLanguage = getHttpServletRequest().getHeader(HttpHeaders.ACCEPT_LANGUAGE);
        return StringUtils.isBlank(acceptLanguage) ? Locale.getDefault() : Locale.forLanguageTag(acceptLanguage);
    }

    /**
     * 获取客户端UserAgent
     *
     * @return UserAgent
     */
    public static UserAgent getClientUserAgent() {
        return UserAgentUtil.parse(getHttpServletRequest().getHeader(Header.USER_AGENT.toString()));
    }

    /**
     * 获取 HttpServletRequest
     *
     * @return {@link HttpServletRequest}
     */
    public static HttpServletRequest getHttpServletRequest() {
        return getServletRequestAttributes().getRequest();
    }

    /**
     * 获取 ServletRequestAttributes
     *
     * @return {@link ServletRequestAttributes}
     */
    public static ServletRequestAttributes getServletRequestAttributes() {
        return (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    }

    /**
     * 获取响应数据
     *
     * @param response response
     * @param <T>      data的java类型
     * @return response.data
     */
    public static <T> T getData(Response<T> response) {
        Metric metric = response.getMetric();
        if (metric.isSuccess()) {
            return response.getData();
        }
        log.error("Service return a failed info. Error code: {}, msg: {}", metric.getMsgCode(), metric.getMsgDesc());
        throw new ServiceCallException(metric.getMsgCode(), metric.getMsgDesc());
    }

    public static String getTraceId() {
        return getHttpServletRequest().getHeader(TRANCE_ID_KEY);
    }
}